using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlTypes;
using Spring.Data;
using Spring.Data.Generic;
using Spring.Data.Common;
using Spring.Data.Objects.Generic;

namespace MySearch
{
    public enum EventAction
    {
        CreateTicket, UpdateTicket, WithDrawTicket,
        CreateTicketData, UpdateTicketData,
        CreateTicketStep, UpdateTicketStep,
        createTicketDialogue, UpdateTicketDialogue,

        CreateServiceCategory, UpdateServiceCategory,
        CreateServiceType, UpdateServiceType, CreateServiceTypeVersion,
        CreateServiceStep, CreateServiceStepVersion,
        CreateServiceQuestion, CreateServiceQuestionVersion,

        CreateTeamMember, DeleteTeamMember, UpdateToTeamLeader, UpdateToTeamMember, DeleteTeam, CreateTeam, UpdateTeam,
        CreateAgentTeamServiceType, DeleteAgentTeamServiceType,

        CreateNotification, ProcessNotification,

        SyncProfile, SyncChargeable,

        AppError, AppErrorDebug,

        CreateProfile, UpdateProfile, UpdateProfileField, UpdateProfileMember,
        CreateChargeable, UpdateChargeable, UpdateChargeableMember, UpdateChargeableField,

        CreateSearch, DeleteSearch
    }

    public class EventLog
    {
        public int ID { get; set; }
        public string EventID { get; set; }
        public string ActionType { get; set; }
        public DateTime ActionTime { get; set; }
        public string Operator { get; set; }
        public string Remark { get; set; }

        public EventLog() { }

        public EventLog(string id, string eType, string oper, string remark)
        {
            this.EventID = id;
            this.ActionType = eType;
            this.ActionTime = DateTime.Now;
            this.Operator = oper;
            this.Remark = remark;
        }
    }

    public static class EventLogDAO
    {
        private static AdoTemplate template = AppConfigurer.AdoTemplate;
        private static int _Max_Log_lenght = 4000;

        #region list methods
        private static string strBase = "select id, Event_id, action_type, action_time, operator, remark  "
            + " from event_log ";
        public static IList<EventLog> ListObjects(string eventId)
        {
            //Check parameter
            if (String.IsNullOrEmpty(eventId))
                return new List<EventLog>();

            //Execute Query 
            string strSel = strBase + " where Event_id = @eventid "
                + " order by action_time desc ";
            IDbParameters p = template.CreateDbParameters();
            p.Add("eventid", DbType.String).Value = eventId;

            IList<EventLog> list = template.QueryWithRowMapperDelegate(CommandType.Text, strSel,
                new RowMapperDelegate<EventLog>(MapRow), p);

            return list;
        }

        public static IList<EventLog> ListObjects(string eventId, int TopNumOfRecentlyTime)
        {
            //Check parameter
            if (String.IsNullOrEmpty(eventId) || TopNumOfRecentlyTime <= 0)
                return new List<EventLog>();

            string strSel = "select top " + TopNumOfRecentlyTime.ToString()
                + " id, Event_id, action_type, action_time, operator, remark from event_log "
                + " where event_id=@eventid "
                + " order by action_time desc ";
            IDbParameters p = template.CreateDbParameters();
            p.Add("eventid", DbType.String).Value = eventId;

            IList<EventLog> list = template.QueryWithRowMapperDelegate(CommandType.Text, strSel, 
                new RowMapperDelegate<EventLog>(MapRow), p);

            return list;
        }

        public static IList<EventLog> ListObjects(DateTime dtStart, DateTime dtend)
        {
            //Execute Query 
            string strSel = strBase + " where action_time > @startTime "
                + " and action_time < @endTime "
                + " order by action_time desc ";

            IDbParameters p = template.CreateDbParameters();
            p.Add("startTime", DbType.DateTime).Value = dtStart;
            p.Add("endTime", DbType.DateTime).Value = dtend;

            IList<EventLog> list = template.QueryWithRowMapperDelegate(CommandType.Text, strSel,
                new RowMapperDelegate<EventLog>(MapRow), p);

            return list;
        }
        #endregion

        internal static void newObject(EventLog obj)
        {
            string strUpd = "insert into event_log(Event_id, action_type, action_time, operator, remark) "
                + " values(@id, @actionType, @actionTime, @actionBy, @remark)";

            IDbParameters p = template.CreateDbParameters();
            p.Add("id", DbType.String).Value = obj.EventID;
            p.Add("actionType", DbType.String).Value = obj.ActionType;
            p.Add("actionTime", DbType.DateTime).Value = obj.ActionTime;
            p.Add("actionBy", DbType.String).Value = obj.Operator;
            if (obj.Remark.Length > _Max_Log_lenght)
                obj.Remark = obj.Remark.Substring(0, _Max_Log_lenght);
            p.Add("remark", DbType.String).Value = obj.Remark;

            template.ExecuteNonQuery(CommandType.Text, strUpd, p);
        }

        #region mapper
        private static EventLog MapRow(IDataReader results, int rowNumber)
        {
            EventLog obj = new EventLog();

            obj.ID = results.GetInt32(0);
            obj.EventID = results.GetString(1);
            obj.ActionType = results.GetString(2);
            obj.ActionTime = results.GetDateTime(3);
            obj.Operator = results.GetString(4);
            obj.Remark = results.GetString(5);

            return obj;
        }
        #endregion
    }

    public static class LogUtil
    {
        private static string _SystemEventID = "000000";

        public static void LogEvent(string evtID, EventAction evtType, string oper, string remark)
        {
            EventLog log = new EventLog(evtID, evtType.ToString(), oper, remark);
            EventLogDAO.newObject(log);
        }

        public static void LogEvent(string evtID, string evt, string oper, string remark)
        {
            EventLog log = new EventLog(evtID, evt, oper, remark);
            EventLogDAO.newObject(log);
        }

        public static void LogEvent(string evtID, EventAction evtType, string oper, 
            IDictionary<string, string> dicChange)
        {
            string strRemark = "NA";

            if (dicChange != null && dicChange.Count != 0)
            {
                StringBuilder sb = new StringBuilder();
                foreach (KeyValuePair<string, string> kv in dicChange)
                        sb.Append("," + kv.Key + ":" + kv.Value);
     
                sb.Remove(0, 1);  //Remove the first ","

                strRemark = sb.ToString();
            }

            LogEvent(evtID, evtType, oper, strRemark);
        }

        public static void LogAppEvent(string oper, string remark)
        {
            EventLog log = new EventLog(_SystemEventID, "AppEvent", oper, remark);
            EventLogDAO.newObject(log);
        }

        public static void LogException(string evtID, string oper, Exception ex)
        {
            if (ex == null)
                return;

            if (String.IsNullOrEmpty(evtID))
                evtID = _SystemEventID;

            if (String.IsNullOrEmpty(oper))
                oper = AppConfigurer.SystemUserID;

            EventLog log = new EventLog(evtID, EventAction.AppError.ToString(), oper, ex.Message);
            EventLogDAO.newObject(log);

            if (ex.InnerException != null)
            {
                log = new EventLog(evtID, EventAction.AppErrorDebug.ToString(), oper, ex.InnerException.Message);
                EventLogDAO.newObject(log);
            }
        }
    }
}


